import fs from "fs-extra";
import path from "path";
import { PlayerManager } from "./Biz/PlayerManager"
import { RoomManager } from "./Biz/RoomManager"
import {
    ApiMsgEnum, GHomeMaxPlayerNum, IApiApplyOfflineLaunchReq, IApiGameStartReq, IApiLoginReq, IApiLoginRes, IApiMidJoinGameReq, initSelectPool,
    IApiPlayerCancelReadyReq, IApiPlayerReadyReq, IApiRoomCreateReq, IApiRoomCreateRes, IApiRoomJoinReq, IApiRoomJoinRes, initEntity, initExp,
    IApiRoomLeaveReq, IApiRoomListReq, IApiRoomListRes, initGlobal, initChapter, initLevelPart, initWeapon, initProp,
} from "./Common"
import { Connection } from "./Core/Connection"
import { MyServer, ServerEventType } from "./Core/MyServer"
import { symlinkCommon } from "./Utils"

symlinkCommon()

const server = new MyServer(8888)
const folderPath = './json'
server.on(ServerEventType.connection, (connection: Connection) => {
    console.log('有玩家建立了链接')
})

server.on(ServerEventType.disconnection, (connection: Connection) => {
    PlayerManager.Ins.playerOffline(connection.playerId)
})

server.setApi(ApiMsgEnum.ApiLogin, (connection: Connection, data: IApiLoginReq): IApiLoginRes => {

    const { nickName } = data


    const res = PlayerManager.Ins.playerOfflineLaunch(nickName, connection)
    if (res) {
        console.log(`玩家${nickName}断线重连了`)
        return {
            player: res,
            isOfflineConnection: true
        }
    }

    if (PlayerManager.Ins.checkNickName(nickName)) {
        throw new Error('昵称重复')
    }

    const player = PlayerManager.Ins.creatPlayer({ connection, nickName })
    connection.playerId = player.id
    console.log(`玩家${nickName}进入了大厅`)
    return {
        player: PlayerManager.Ins.getPlayerView(player)
    }
})

server.setApi(ApiMsgEnum.ApiRoomList, (connection: Connection, data: IApiRoomListReq): IApiRoomListRes => {
    return {
        rooms: RoomManager.Ins.getRoomsView()
    }
})

server.setApi(ApiMsgEnum.ApiRoomCreate, (connection: Connection, data: IApiRoomCreateReq): IApiRoomCreateRes => {
    const room = RoomManager.Ins.createRoom()
    room.join(connection.playerId)

    RoomManager.Ins.syncHall()
    return {
        room: RoomManager.Ins.getRoomView(room)
    }
})

server.setApi(ApiMsgEnum.ApiRoomJoin, (connection: Connection, data: IApiRoomJoinReq): IApiRoomJoinRes => {
    if (connection.playerId) {
        const room = RoomManager.Ins.getRoomById(data.rid)

        if (room) {
            const players = [...room.players]
            if (players.length >= GHomeMaxPlayerNum) {
                throw new Error('房间人数已满')
            }
            room.join(connection.playerId)
            RoomManager.Ins.syncHall()
            room.syncRoom()
            return {
                room: RoomManager.Ins.getRoomView(room)
            }
        } else {
            throw new Error('房间不存在')
        }
    } else {
        throw new Error('未登录')
    }

})

server.setApi(ApiMsgEnum.ApiRoomLeave, (connection: Connection, data: IApiRoomLeaveReq): any => {
    if (connection.playerId) {
        const player = PlayerManager.Ins.idMapPlayers.get(connection.playerId)
        if (player) {
            const room = RoomManager.Ins.getRoomById(player.rid)
            if (room) {
                room.leave(connection.playerId)
                RoomManager.Ins.syncHall()
                room.syncRoom()
            } else {
                throw new Error('房间不存在')
            }
        } else {
            throw new Error('玩家不存在')
        }
    } else {
        throw new Error('未登录')
    }
})

server.setApi(ApiMsgEnum.ApiPlayerReady, (connection: Connection, data: IApiPlayerReadyReq): any => {
    if (connection.playerId) {
        const player = PlayerManager.Ins.idMapPlayers.get(connection.playerId)
        if (player) {
            const room = RoomManager.Ins.getRoomById(player.rid)
            if (room) {
                if (player.ready !== 1) {
                    player.ready = 1
                    room.syncRoom()
                } else {
                    throw new Error('已经准备了')
                }
            } else {
                throw new Error('房间不存在')
            }
        } else {
            throw new Error('玩家不存在')
        }
    } else {
        throw new Error('未登录')
    }
})

server.setApi(ApiMsgEnum.ApiPlayerCancelReady, (connection: Connection, data: IApiPlayerCancelReadyReq): any => {
    if (connection.playerId) {
        const player = PlayerManager.Ins.idMapPlayers.get(connection.playerId)
        if (player) {
            const room = RoomManager.Ins.getRoomById(player.rid)
            if (room) {
                if (player.ready === 1) {
                    player.ready = 0
                    room.syncRoom()
                } else {
                    throw new Error('未准备')
                }
            } else {
                throw new Error('房间不存在')
            }
        } else {
            throw new Error('玩家不存在')
        }
    } else {
        throw new Error('未登录')
    }
})

server.setApi(ApiMsgEnum.ApiGameStart, (connection: Connection, data: IApiGameStartReq): any => {
    if (connection.playerId) {
        const player = PlayerManager.Ins.idMapPlayers.get(connection.playerId)
        if (player) {
            const room = RoomManager.Ins.getRoomById(player.rid)
            if (room) {
                const players = [...room.players]
                if (players[0].id !== connection.playerId) {
                    throw new Error('你不是房主')
                }
                players.forEach(player => {
                    if (player.ready === 0) {
                        throw new Error('有玩家尚未准备')
                    }
                })
                room.gameStart()
            } else {
                throw new Error('房间不存在')
            }
        } else {
            throw new Error('玩家不存在')
        }
    } else {
        throw new Error('未登录')
    }
})

server.setApi(ApiMsgEnum.ApiApplyOfflineLaunch, (connection: Connection, data: IApiApplyOfflineLaunchReq): any => {

    const player = PlayerManager.Ins.idMapPlayers.get(connection.playerId)
    if (player) {
        const room = RoomManager.Ins.getRoomById(player.rid)
        if (room) {
            const players = [...room.players]
            const p = players.find(v => v.id === player.id)
            if (p) {
                p.readyJoiningMidGame = true
            } else {
                throw new Error('玩家不在房间内')
            }
        } else {
            throw new Error('房间不存在')
        }
    } else {
        throw new Error('玩家不存在')
    }

})

server.setApi(ApiMsgEnum.ApiMidJoinGame, (connection: Connection, data: IApiMidJoinGameReq): any => {

    const player = PlayerManager.Ins.idMapPlayers.get(connection.playerId)
    if (player) {
        const room = RoomManager.Ins.getRoomById(player.rid)
        if (room) {
            room.applyJoneGaming(player)
        } else {
            throw new Error('房间不存在')
        }
    } else {
        throw new Error('玩家不存在')
    }

})

fs.readdir(folderPath, (err, files) => {
    if (err) {
        console.error(err);
        return;
    }

    const jsonFiles = files.filter(file => path.extname(file).toLowerCase() === '.json');

    const data: Record<string, any> = {}
    jsonFiles.forEach(file => {
        const filePath = path.join(folderPath, file);
        const fileContent = fs.readFileSync(filePath, 'utf8');
        const jsonData = JSON.parse(fileContent);
        data[file.split('.')[0]] = jsonData
    });
    initGlobal(data['global'])
    console.log('=== 加载完成 global json')

    initWeapon(data['weapon'])
    console.log('=== 加载完成 weapon json')

    initProp(data['prop'])
    console.log('=== 加载完成 prop json')

    initExp(data['exp'])
    console.log('=== 加载完成 exp json')

    initSelectPool(data['selectPool'])
    console.log('=== 加载完成 selectPool json')

    initEntity(data['entity'])
    console.log('=== 加载完成 entity json')

    let index = 1
    const func = () => {
        initChapter(data['chapter' + index], index)
        console.log(`=== 加载完成 chapter${index} json`)
        index++
        if (data['chapter' + index]) {
            func()
        }
    }
    func()

    initLevelPart(data['levelPart'])
    console.log('=== 加载完成 levelPart json')

    server.start()
})
